using System;
using System.IO;
using System.Collections;
using System.Resources;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using ComponentFactory.Krypton.Toolkit;

namespace Zebra.WinFramework
{
	/// <summary>
	/// Manages a collection of MessageBoxes. Basically manages the
	/// saved response handling for messageBoxes.
	/// </summary>
	public class MessageBoxExManager
	{
        #region Fields
        private static Hashtable _messageBoxes = new Hashtable();
        private static Hashtable _savedResponses = new Hashtable();

        private static Hashtable _standardButtonsText = new Hashtable();

        //[DllImport("user32.dll", CharSet = CharSet.Auto)]
        //static extern int LoadString(IntPtr hInstance, uint uID, StringBuilder lpBuffer, int nBufferMax);
        //[DllImport("kernel32")]
        //static extern IntPtr LoadLibrary(string lpFileName);
        //[DllImport("kernel32.dll")]
        //public static extern bool FreeLibrary(IntPtr hModule);

        //private const uint OK_CAPTION = 800;
        //private const uint CANCEL_CAPTION = 801;
        //private const uint ABORT_CAPTION = 802;
        //private const uint RETRY_CAPTION = 803;
        //private const uint IGNORE_CAPTION = 804;
        //private const uint YES_CAPTION = 805;
        //private const uint NO_CAPTION = 806;
        //private const uint CLOSE_CAPTION = 807;
        //private const uint HELP_CAPTION = 808;
        //private const uint TRYAGAIN_CAPTION = 809;
        //private const uint CONTINUE_CAPTION = 810;

        #endregion

        #region Static ctor
        //updated to use local strings if resources not found (thanks http://www.componentfactory.com/forums/viewtopic.php?f=7&t=1969#p9668)
        static MessageBoxExManager()
        {
            //try
            //{
            //    Assembly current = typeof(MessageBoxExManager).Assembly;
            //    string[] resources = current.GetManifestResourceNames();
            //    ResourceManager rm = new ResourceManager("KryptonMessageBoxEx.Resources.StandardButtonsText", typeof(MessageBoxExManager).Assembly);
            //    _standardButtonsText[MessageBoxExButtons.OK.ToString()] = rm.GetString("Ok");
            //    _standardButtonsText[MessageBoxExButtons.Cancel.ToString()] = rm.GetString("Cancel");
            //    _standardButtonsText[MessageBoxExButtons.Yes.ToString()] = rm.GetString("Yes");
            //    _standardButtonsText[MessageBoxExButtons.No.ToString()] = rm.GetString("No");
            //    _standardButtonsText[MessageBoxExButtons.Abort.ToString()] = rm.GetString("Abort");
            //    _standardButtonsText[MessageBoxExButtons.Retry.ToString()] = rm.GetString("Retry");
            //    _standardButtonsText[MessageBoxExButtons.Ignore.ToString()] = rm.GetString("Ignore");
            //}
            //catch (Exception ex)
            //{
            //    System.Diagnostics.Debug.Assert(false, "Unable to load resources for MessageBoxEx", ex.ToString());

            //    StringBuilder sb = new StringBuilder(256);
            //    IntPtr user32 = LoadLibrary(Environment.SystemDirectory + "\\User32.dll");

            //    LoadString(user32, OK_CAPTION, sb, sb.Capacity);
            //    _standardButtonsText[MessageBoxExButtons.OK.ToString()] = sb.ToString();

            //    LoadString(user32, CANCEL_CAPTION, sb, sb.Capacity);
            //    _standardButtonsText[MessageBoxExButtons.Cancel.ToString()] = sb.ToString();

            //    LoadString(user32, YES_CAPTION, sb, sb.Capacity);
            //    _standardButtonsText[MessageBoxExButtons.Yes.ToString()] = sb.ToString();

            //    LoadString(user32, NO_CAPTION, sb, sb.Capacity);
            //    _standardButtonsText[MessageBoxExButtons.No.ToString()] = sb.ToString();

            //    LoadString(user32, ABORT_CAPTION, sb, sb.Capacity);
            //    _standardButtonsText[MessageBoxExButtons.Abort.ToString()] = sb.ToString();

            //    LoadString(user32, RETRY_CAPTION, sb, sb.Capacity);
            //    _standardButtonsText[MessageBoxExButtons.Retry.ToString()] = sb.ToString();

            //    LoadString(user32, IGNORE_CAPTION, sb, sb.Capacity);
            //    _standardButtonsText[MessageBoxExButtons.Ignore.ToString()] = sb.ToString();

            //    FreeLibrary(user32);
            //}
        }

        #endregion

		#region Methods

        public static MessageBoxEx CreateMessageBox(string name)
        {
            return CreateMessageBox(name, PaletteModeManager.Office2007Blue, null);
        }


		/// <summary>
		/// Creates a new message box with the specified name. If null is specified
		/// in the message name then the message box is not managed by the Manager and
		/// will be disposed automatically after a call to Show()
		/// </summary>
        /// <param name="name">The name of the message box</param>
        /// <param name="palette">The Krypton palette of the message box</param>
        /// <param name="paletteMode">The Krypton palette mode of the message box</param>
        /// <returns>A new message box</returns>
        public static MessageBoxEx CreateMessageBox(string name, PaletteModeManager paletteMode, IPalette palette)
		{
			if(name != null && _messageBoxes.ContainsKey(name))
			{
				string err = string.Format("A MessageBox with the name {0} already exists.",name);
				throw new ArgumentException(err,"name");
			}

			MessageBoxEx msgBox = new MessageBoxEx();
			msgBox.Name = name;
		   // msgBox.GlobalPalette = palette;
		    //msgBox.GlobalPaletteMode = paletteMode;

			if(msgBox.Name != null)
			{
				_messageBoxes[name] = msgBox;
			}

			return msgBox;
		}

		/// <summary>
		/// Gets the message box with the specified name
		/// </summary>
		/// <param name="name">The name of the message box to retrieve</param>
		/// <returns>The message box with the specified name or null if a message box
		/// with that name does not exist</returns>
		public static MessageBoxEx GetMessageBox(string name)
		{
			if(_messageBoxes.Contains(name))
			{
				return _messageBoxes[name] as MessageBoxEx;
			}
			else
			{
				return null;
			}
		}

		/// <summary>
		/// Deletes the message box with the specified name
		/// </summary>
		/// <param name="name">The name of the message box to delete</param>
		public static void DeleteMessageBox(string name)
		{
			if(name == null)
				return;

			if(_messageBoxes.Contains(name))
			{
				MessageBoxEx msgBox = _messageBoxes[name] as MessageBoxEx;
				msgBox.Dispose();
				_messageBoxes.Remove(name);
			}
		}

		public static void WriteSavedResponses(Stream stream)
		{
			throw new NotImplementedException("This feature has not yet been implemented");
		}

		public static void ReadSavedResponses(Stream stream)
		{
			throw new NotImplementedException("This feature has not yet been implemented");
		}

		/// <summary>
		/// Reset the saved response for the message box with the specified name.
		/// </summary>
		/// <param name="messageBoxName">The name of the message box whose response is to be reset.</param>
		public static void ResetSavedResponse(string messageBoxName)
		{
            if(messageBoxName == null)
                return;

			if(_savedResponses.ContainsKey(messageBoxName))
			{
				_savedResponses.Remove(messageBoxName);
			}
		}

		/// <summary>
		/// Resets the saved responses for all message boxes that are managed by the manager.
		/// </summary>
		public static void ResetAllSavedResponses()
		{
			_savedResponses.Clear();
		}
		#endregion

		#region Internal Methods
		/// <summary>
		/// Set the saved response for the specified message box
		/// </summary>
		/// <param name="msgBox">The message box whose response is to be set</param>
		/// <param name="response">The response to save for the message box</param>
		internal static void SetSavedResponse(MessageBoxEx msgBox, string response)
		{
            if(msgBox.Name == null)
                return;

			_savedResponses[msgBox.Name] = response;
		}

		/// <summary>
		/// Gets the saved response for the specified message box
		/// </summary>
		/// <param name="msgBox">The message box whose saved response is to be retrieved</param>
		/// <returns>The saved response if exists, null otherwise</returns>
		internal static string GetSavedResponse(MessageBoxEx msgBox)
		{
			string msgBoxName = msgBox.Name;
            if(msgBoxName == null)
            {
                return null;
            }

			if(_savedResponses.ContainsKey(msgBoxName))
			{
				return _savedResponses[msgBox.Name].ToString();
			}
			else
			{
				return null;
			}
		}

        /// <summary>
        /// Returns the localized string for standard button texts like,
        /// "Ok", "Cancel" etc.
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        internal static string GetLocalizedString(string key)
        {
            if(_standardButtonsText.ContainsKey(key))
            {
                return (string)_standardButtonsText[key];
            }
            else
            {
                return null;
            }
        }
		#endregion
	}
}
